package com.otaliastudios.cameraview.video

import android.graphics.Bitmap
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.SystemClock
import android.view.PixelCopy
import android.view.Surface
import com.otaliastudios.cameraview.LogPlus
import com.otaliastudios.cameraview.VideoResult
import com.otaliastudios.cameraview.livedata.FpsLiveData
import com.otaliastudios.cameraview.livedata.RecordPauseLiveData
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import org.opencv.android.OpenCVLoader
import org.opencv.android.Utils
import org.opencv.core.Mat
import org.opencv.core.Size
import org.opencv.videoio.VideoWriter
import java.io.File


class AviMatEncoder(private val surface: Surface, private val result: VideoResult.Stub) {
    val fps = FpsLiveData.get()
    private val videoWriter by lazy {
        VideoWriter(
            result.file.absolutePath,
            VideoWriter.fourcc('M', 'J', 'P', 'G'),
            (fps.value ?: 15).coerceAtMost(result.videoFrameRate).toDouble(),
            Size(result.size.width.toDouble(), result.size.height.toDouble())
        )
    }
    private val mat by lazy { Mat() }
    private val scrBitmap by lazy {
        Bitmap.createBitmap(
            result.size.width,
            result.size.height, Bitmap.Config.ARGB_8888
        )
    }
    private val handler by lazy { Handler(Looper.getMainLooper()) }
    var recordJob: Job? = null

    fun start() {
        recordJob = GlobalScope.launch(IO) {
            val fps = (fps.value ?: 15).coerceAtMost(result.videoFrameRate)
            val fpsInterval = 1000L / fps
            var count = 0
            var fristTime = SystemClock.elapsedRealtime()
            while (isActive) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    val start = SystemClock.elapsedRealtime()
                    if (surface.isValid) {
                        PixelCopy.request(surface, scrBitmap, {}, handler)
                        Utils.bitmapToMat(scrBitmap, mat)
                        if (RecordPauseLiveData.get().value != true)
                            videoWriter.write(mat)
                        val cha = SystemClock.elapsedRealtime() - start
                        LogPlus.i("bitmap转Mat花费===>$cha")
                        if (fpsInterval - cha > 4) {
                            delay(fpsInterval - cha - 4)
                        }
                        count++
                        if (count % fps == 0) {
                            LogPlus.w("${fps}帧花费时间==>${SystemClock.elapsedRealtime() - fristTime}")
                            fristTime = SystemClock.elapsedRealtime()
                        }
                    }else{
                        videoWriter.release()
                        error("Surface isn't valid")
                    }
                } else {
                    videoWriter.release()
                    error("当前功能只支持android7.0以上版本")
                }
            }
            videoWriter.release()
            mat.release()
            scrBitmap.recycle()
            LogPlus.e("关闭AVI录像了")
        }
    }

    fun stopAviRecord() {
        recordJob?.cancel()


    }

    init {
        LogPlus.w("当前的帧率==>${result.videoFrameRate}")
    }
}